import 'reflect-metadata';
import KoaRouter from 'koa-router';
import Koa from 'koa';


export const RequestMethod = {
    GET: 'get',
    POST: 'post',
    PUT: 'put',
    PATCH: 'patch',
    DELETE: 'delete',
    OPTION: 'option'
}

export type MethodType = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'option';

export interface ControllerParam {
    prefix?: string
}

export interface RequestParam {
    url: string;
    method: MethodType;
    middleware?: any[];
}

export function Controller({ prefix }: ControllerParam) {
    let router = new KoaRouter();
    router.prefix(prefix || '');
    return function (target: any) {
        let targetDescriptors = Object.getOwnPropertyDescriptors(target.prototype);
        for (let descriptor in targetDescriptors) {
            let currentDescriptor = targetDescriptors[descriptor].value;
            if (descriptor !== 'constructor' && typeof (currentDescriptor) === 'function') {
                currentDescriptor(router);
            }
        }
        return router as any;
    }
}

export function Request({ url, method, middleware = [] }: RequestParam) {
    return function (target: any, name: string, descriptor: PropertyDescriptor) {
        let currentFn = descriptor.value;
        descriptor.value = (router: any) => {
            if (router && typeof (router[method]) === 'function') {
                router[method](url, ...middleware, async (ctx: Koa.Context, next: Koa.Next) => {
                    await currentFn(ctx, next);
                })
            } else {
                currentFn();
            }
        }
    }
}